package vn.fpt.snake.ui;

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;

import vn.fpt.snake.commons.Constants;
import vn.fpt.snake.commons.Direction;
import vn.fpt.snake.controller.FruitControllerImpl;
import vn.fpt.snake.controller.GameControllerImpl;
import vn.fpt.snake.controller.SnakeControllerImpl;
import vn.fpt.snake.entity.Apple;
import vn.fpt.snake.entity.Chili;
import vn.fpt.snake.entity.Settings;
import vn.fpt.snake.entity.Snake;
import vn.fpt.snake.entity.Watermelon;
import vn.fpt.snake.view.Board;
import vn.fpt.snake.entity.AbstractFruit;

public class BoardViewImpl implements IView {
	Board parent;
	Snake snake;
	Snake enemy;
	public Direction direction;
	List<AbstractFruit> fruits;
	List<Snake> snakes;
	SnakeControllerImpl snakeController;
	FruitControllerImpl fruitController;
	GameControllerImpl gameController;
	int numberEat = 1;
	Settings settings;
	int dotSize;
	boolean isPause;

	public BoardViewImpl(Board parent) throws Exception {
		this.parent = parent;
		init();
	}

	public void init() throws Exception {
		snakeController = new SnakeControllerImpl(parent);
		fruitController = new FruitControllerImpl();
		gameController = new GameControllerImpl();

		settings = gameController.getSettings();
		direction = Direction.none;
		isPause = false;
		fruits = new ArrayList<AbstractFruit>();
		snakes = new ArrayList<Snake>();
		dotSize = settings.getDotSize();

		snake = snakeController.createNewSnake();
		//enemy = snakeController.createNewSnake();

		snakes.add(snake);
		//snakes.add(enemy);
		Apple apple = fruitController.createNewApple();
		Watermelon watermelon = fruitController.createNewWatermelon();
		Chili chili = fruitController.createNewChili();

		fruits.add(apple);
		fruits.add(watermelon);
		fruits.add(chili);
	}

	@Override
	public void onPaint(Graphics g) {
		// TODO Auto-generated method stub
		try {
			g.drawImage(gameController.getImage(Constants.BG_IMG), 0, 0, parent.width, parent.height, parent);
			drawSnake(g);
			drawFruit(g);
			drawScore(g);
			if (direction != Direction.none) {
				// Snake is future in next step
				snakeController.move(snake, direction);
				//snakeController.ai(enemy);
				snakeController.checkCollision(snake);
			
				// Check snake eat apple ?
				if (snakeController.eatFruit(snake, fruits)) {
					numberEat++;
					int dots = snake.getDots();
					snake.setDots(dots + 1);
				}
				// Locate watermelon depends on numberEat
				if (numberEat != 0 && (numberEat % 2) == 0) {
					fruitController.locateWatermelon(fruits);
					numberEat++;
				}
				// Locate chili depends on Chili
				if (numberEat != 0 && (numberEat % 3) == 0) {
					fruitController.locateChili(fruits);
					numberEat++;
				}
			}
			if (isPause) {
				drawPausedScreen(g);
				gameController.pauseGame(parent);
				
			}

		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
	}

	public void drawSnake(Graphics g) {
		if (snakes != null) {
			for (Snake s : snakes) {
				for (int i = 0; i < s.getDots(); i++) {
					if (i == 0)
						g.drawImage(s.getHead(), s.getX(i), s.getY(i), dotSize,
								dotSize, parent);
					else
						g.drawImage(s.getDot(), s.getX(i), s.getY(i), dotSize,
								dotSize, parent);
				}
			}
		}
	}

	public void drawScore(Graphics g) {
		Font font = new Font("Cooper Black", Font.BOLD, dotSize);
		g.setColor(Color.YELLOW);
		g.setFont(font);
		g.drawString(String.format(Constants.SCORE, snake.getScore()), dotSize, dotSize);
	}

	public void drawFruit(Graphics g) {
		for (AbstractFruit fruit : fruits) {
			g.drawImage(fruit.getIcon(), fruit.getX(), fruit.getY(), dotSize,
					dotSize, parent);
		}
	}

	public void drawPausedScreen(Graphics g) throws Exception{
		g.drawImage(gameController.getImage(Constants.PAUSE_IMG), 0, 0, parent.width, parent.height, parent);
		Font font = new Font("Cooper Black", Font.BOLD, dotSize);
		FontMetrics metrics = g.getFontMetrics(font);
		g.setColor(Color.white);
		g.setFont(font);
		String pause = Constants.PAUSED;
		int widthText = metrics.stringWidth(pause);
		int xText = (parent.width - widthText) / 2;
		int yText = (parent.height - dotSize) / 2;
		g.drawString(pause, xText, yText);
	}

	@Override
	public void keyPressed(KeyEvent arg) {
		// TODO Auto-generated method stub
		int keyCode = arg.getKeyCode();
		if (parent._view instanceof BoardViewImpl) {
			BoardViewImpl boardView = (BoardViewImpl) parent._view;
			if (keyCode == KeyEvent.VK_W
					&& boardView.direction != Direction.down) {
				boardView.direction = Direction.up;
			} else if (keyCode == KeyEvent.VK_A
					&& boardView.direction != Direction.right) {
				boardView.direction = Direction.left;
			} else if (keyCode == KeyEvent.VK_S
					&& boardView.direction != Direction.up) {
				boardView.direction = Direction.down;
			} else if (keyCode == KeyEvent.VK_D
					&& boardView.direction != Direction.left) {
				boardView.direction = Direction.right;
			} else if (keyCode == KeyEvent.VK_SPACE) {
				if (parent.timer.isRunning()) {
					isPause = true;
				} else {
					isPause = false;
					gameController.resumeGame(parent);
				}
			}
		}
	}

	@Override
	public void keyReleased(KeyEvent arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void keyTyped(KeyEvent arg0) {
		// TODO Auto-generated method stub

	}
}
